
#pragma once
#include <sys/types.h>
#include <sys/socket.h>
#include"InetAddr.hpp"
#include<iostream>
#include<string>
#include<list>
#include<memory>
#include"Log.hpp"
#include"Mutex.hpp"
#include<algorithm>
using namespace std;
using namespace LogModule;
using namespace LockModule;

class UserInterface //用户接口类
{
public:
   virtual ~UserInterface() = default;
   virtual void SendTo(int sockfd,const string& message) = 0;//发给指定用户消息
   virtual bool operator==(const InetAddr& u) = 0;    
   virtual string Id() = 0;    


};


class User : public UserInterface
{
public:
  User(const InetAddr& id)
   :_id(id)  
  {}
  ~User(){}
  void SendTo(int sockfd,const string& message) override
  {
      LOG(LogLevel::DEBUG) << "Send messege to" << _id.Addr() << "info: " << message << "\n";
      int n = ::sendto(sockfd,message.c_str(),message.size(),0,_id.Netaddr(),_id.NetAddrLen());
  }
  
  bool operator==(const InetAddr& u)
  {
      return _id == u; //还需要对IneAddr重载==
  }

  string Id()
  {
    return _id.Addr();
  }

private: 
   InetAddr _id;

};

//对用户消息进行路由->需要把所有用户先管理起来
class UserManager 
{
public:
   UserManager(){}

   ~UserManager(){}

   void AddUser( InetAddr& id ) //新增用户
   {
    LockGuard lockguard(_mutex);
    for(auto& user : _online_user)//查看是否已经存在该用户
    {
        if(*user == id) 
        {
            LOG(LogLevel::INFO) << id.Addr() <<"用户已经存在" << "\n";
            return ;//存在则不添加
        }
    }
    LOG(LogLevel::INFO) <<  "新增该用户" << id.Addr() << "\n";
    //先得有用户
    _online_user.push_back(make_shared<User>(id));
    PrintUser();
      
   }

   void DelUser(InetAddr& id) //删除一个用户
   {
       //相等就移除 remove_if没有真的移除而是把元素列到了结尾，遍历时不允许你访问了
       auto pos = ::remove_if(_online_user.begin(),_online_user.end(),[&id](shared_ptr<UserInterface>& user){
        return *user == id;
       });

       _online_user.erase(pos,_online_user.end());
       PrintUser();
      //  //v2
      //  for(auto& user:_online_user)
      //  {
      //     if(*user == id)
      //     {
      //       _online_user.erase(user);
      //       break; //迭代器失效
      //     }
      //  }

   }

   void Router(int sockfd,const string& message) //消息转发
   {
     LockGuard lockguard(_mutex);
     for(auto& user:_online_user)
     {
         user->SendTo(sockfd,message);//遍历每一个User提供的SendTo方法
     }
   }

   void PrintUser()
   {
      for(auto user:_online_user)
      {
         LOG(LogLevel::DEBUG) << "在线用户-> " << user->Id();
      }

   }

private:
  list<shared_ptr<UserInterface>> _online_user;
  Mutex _mutex;
};